package my.georings;

import java.util.ArrayList;
import java.util.List;

import my.Utils;
import my.georings.data.MyLocation;
import my.georings.data.MyLocationCurrent;
import my.georings.map.LocationItomizedOverlay;
import my.georings.service.LocationChangeService;
import my.georings.service.MyLocationChangedListener;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.Toast;
import android.widget.AdapterView.OnItemSelectedListener;

import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;



public class MyMapActivity extends MapActivity implements OnItemSelectedListener, MyLocationChangedListener{

	protected LocationItomizedOverlay overlays;
	protected MapView mapView;
	protected MyLocationCurrent myLocation = new MyLocationCurrent();
	
	protected LocationChangeService boundService;
	private int currentFilterIndex = 0;
	protected boolean firstTime = true;
	
	protected ProgressDialog progressDialog;
	
	
	public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.map);
        
        Drawable drawable = this.getResources().getDrawable(R.drawable.pin);
        overlays = new LocationItomizedOverlay(drawable, this);
        
        mapView = (MapView) findViewById(R.id.MapView);
        
        initSpinner();
        initMapView();
    }
	
	@Override
	protected void onResume(){
		super.onResume();
		
		if(firstTime && ((GeoPhoneRingsApp)getApplication()).checkServiceRunning()){
			progressDialog = ProgressDialog.show(this, "", 
                    "Getting your current location. Please wait...", false);
			
        }
		
		boolean hasLocation = false;
		
		if(((GeoPhoneRingsApp)getApplication()).checkServiceRunning()){
        	doBindService();
        }else if(((GeoPhoneRingsApp)getApplication()).isRestart()){
        	onNoProviderAvailable();
        	return;
        }else{
        	LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
        	Location lastLocation = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
    		if(lastLocation == null)
    			lastLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
    		
    		if(lastLocation == null){
    			Utils.showToast(this, "The application could not get your last location. Please turn on the service on settings tab.", Toast.LENGTH_SHORT);
    		}else{
    			Utils.showToast(this, "Your location may not be accurate. Please turn on the service on settings tab.", Toast.LENGTH_SHORT);
    			myLocation.setPoint(Utils.geoPointFromLocation(lastLocation));
    			hasLocation = true;
    		}
        }
		
		refreshLocationOverlays();
		if(hasLocation)
			refreshCurrentLocationView();
	}
	
	@Override
	protected void onPause(){
		doUnbindService();
		super.onPause();
	}
	
	
	@Override
	protected boolean isRouteDisplayed(){
		return false;
	}
	
	private void initMapView(){
        mapView.setBuiltInZoomControls(true);
        mapView.getController().setZoom(15);
	}
	
	protected void refreshCurrentLocationView(){
		if(myLocation.getPoint() == null){
			return;
		}
		
		overlays.addLocationItem(myLocation);
		mapView.invalidate();
		
		if(LocationChangeService.TEST)
			mapView.getController().animateTo(myLocation.getPoint());
		
		if(firstTime){
			mapView.getController().animateTo(myLocation.getPoint());
		}
	}
	
	private void refreshLocationOverlays(){
		List<Overlay> mapOverlays = mapView.getOverlays();
		
		mapOverlays.clear();
		overlays.clear();
		
		ArrayList<MyLocation> list =  ((GeoPhoneRingsApp)getApplication()).getMyLocationsManager().getList();
		
		for(int i = 0; i < list.size(); ++i){
			MyLocation next = (MyLocation)list.get(i);
			switch(currentFilterIndex){
			case 0: // All
			break;
			
			case 1: // Only on
				if(!next.isON())
					continue;
			break;
			
			case 2: // Only muted
				if(!next.isMute())
					continue;
			break;
				
			case 3: // Only ring changed
				if(!next.isChangeRing())
					continue;
			break;
			}
			overlays.addLocationItem((MyLocation)list.get(i));
		}
		
        mapOverlays.add(overlays);
        if(!firstTime)
        	refreshCurrentLocationView();
	}
	
	
	protected void initSpinner(){
		Spinner spinner = (Spinner) findViewById(R.id.map_filter);
	    ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
	            this, R.array.filter, android.R.layout.simple_spinner_item);
	    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
	    spinner.setAdapter(adapter);
	    spinner.setOnItemSelectedListener(this);
	    spinner.setSelection(currentFilterIndex);
	}
	
	

	@Override
	public void onItemSelected(AdapterView<?> parent, View view, int index, long id) {
		if(currentFilterIndex != index){
			currentFilterIndex = index;
			refreshLocationOverlays();
			mapView.invalidate();
		}
	}

	@Override
	public void onNothingSelected(AdapterView<?> arg0) {}

	
	@Override
	public void onMyLocationChanged(Location newLocation) {
		myLocation.setPoint(Utils.geoPointFromLocation(newLocation));
		myLocation.setAccuracy(newLocation.getAccuracy());
		
		refreshCurrentLocationView();
		if(firstTime){
			if(progressDialog != null)
				progressDialog.dismiss();
			firstTime = false;
		}
	}

	protected void doBindService() {
		Intent myIntent = new Intent(this.getParent(), my.georings.service.LocationChangeService.class);
		this.getParent().bindService(myIntent, boundConnection, Context.BIND_AUTO_CREATE);
	}

	protected void doUnbindService() {
	    if (boundService != null) {
	    	boundService.removeListener(this);
	    	this.getParent().unbindService(boundConnection);
	        boundService = null;
	    }
	}

	protected ServiceConnection boundConnection = new ServiceConnection() {
	    public void onServiceConnected(ComponentName className, IBinder service) {
	    	boundService = ((LocationChangeService.LocationChangeBinder)service).getService();
	    	
	    	if(((GeoPhoneRingsApp)getApplication()).isServiceWasStarted()){
	    		
		    	Location newLocation = boundService.getLastLocation();
		    	if(newLocation == null){
		    		Utils.showToast(MyMapActivity.this, "The application could not get your last location.", Toast.LENGTH_SHORT);
		    	}else{
			    	onMyLocationChanged(newLocation);
		    	}
	    	}
	    	boundService.addListener(MyMapActivity.this);
	    }

	    public void onServiceDisconnected(ComponentName className) {
	    	boundService = null;
	    }
	};


	@Override
	public void onNoProviderAvailable() {
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
    	builder.setMessage("Please turn on gps or wifi localization in your phone settings and restart application.")
    	       .setCancelable(false)
    	       .setTitle("Error")
    	       .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
    	           public void onClick(DialogInterface dialog, int id) {
    	                MyMapActivity.this.finish();
    	           }
    	       });
    	AlertDialog alert = builder.create();
    	alert.show();
	}
	
//	private void onNoLocationAvailabale(){
//		AlertDialog.Builder builder = new AlertDialog.Builder(this);
//    	builder.setMessage("The application cannot get any current localization. Please check if your gps or wifi localization is on and restart application.")
//    	       .setCancelable(false)
//    	       .setTitle("Error")
//    	       .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
//    	           public void onClick(DialogInterface dialog, int id) {
//    	                MyMapActivity.this.finish();
//    	           }
//    	       });
//    	AlertDialog alert = builder.create();
//    	alert.show();
//	}
}
